﻿
Imports System.IO
Imports osi.root.constants
Imports osi.root.connector
Imports osi.root.delegates
Imports osi.root.procedure
Imports osi.root.formation
Imports osi.root.utils
Imports osi.service.convertor
Imports Encoding = System.Text.Encoding

Public Class text_dev_T_adapter(Of T)
    Implements dev_T(Of T)

    Public ReadOnly text_dev As text
    Private ReadOnly T_string As binder(Of _do_val_ref(Of T, String, Boolean), uri_conversion_binder_protector)
    Private ReadOnly string_T As binder(Of _do_val_ref(Of String, T, Boolean), uri_conversion_binder_protector)

    Public Sub New(ByVal t As text,
                   Optional ByVal T_string As binder(Of _do_val_ref(Of T, String, Boolean), 
                                                        uri_conversion_binder_protector) = Nothing,
                   Optional ByVal string_T As binder(Of _do_val_ref(Of String, T, Boolean), 
                                                        uri_conversion_binder_protector) = Nothing)
        assert(Not t Is Nothing)
        assert(T_string.has_value())
        assert(string_T.has_value())
        Me.text_dev = t
        Me.T_string = T_string
        Me.string_T = string_T
    End Sub

    Public Shared Function convert(ByVal i As text,
                                   ByRef o As dev_T(Of T),
                                   Optional ByVal T_bytes As binder(Of _do_val_ref(Of T, String, Boolean), 
                                                                       uri_conversion_binder_protector) = Nothing,
                                   Optional ByVal bytes_T As binder(Of _do_val_ref(Of String, T, Boolean), 
                                                                       uri_conversion_binder_protector) = Nothing) _
                                  As Boolean
        o = New text_dev_T_adapter(Of T)(i, T_bytes, bytes_T)
        Return True
    End Function

    Public Shared Function convert(ByVal i As text,
                                   ByVal o As pointer(Of dev_T(Of T)),
                                   Optional ByVal T_bytes As binder(Of _do_val_ref(Of T, String, Boolean), 
                                                                       uri_conversion_binder_protector) = Nothing,
                                   Optional ByVal bytes_T As binder(Of _do_val_ref(Of String, T, Boolean), 
                                                                       uri_conversion_binder_protector) = Nothing) _
                                  As event_comb
        Return sync_async(Function() As Boolean
                              Dim r As dev_T(Of T) = Nothing
                              Return convert(i, r, T_bytes, bytes_T) AndAlso
                                     eva(o, r)
                          End Function)
    End Function

    Public Shared Function convert(ByVal i As dev_T(Of T), ByRef o As text) As Boolean
        Dim a As text_dev_T_adapter(Of T) = Nothing
        If cast(i, a) AndAlso
           assert(Not a Is Nothing) Then
            o = a.text_dev
            Return True
        Else
            Return False
        End If
    End Function

    Public Function sense(ByVal pending As pointer(Of Boolean),
                          ByVal timeout_ms As Int64) As event_comb Implements dev_T(Of T).sense
        Return text_dev.sense(pending, timeout_ms)
    End Function

    Public Function send(ByVal i As T) As event_comb Implements dev_T(Of T).send
        Dim ec As event_comb = Nothing
        Return New event_comb(Function() As Boolean
                                  Dim s As String = Nothing
                                  If (+T_string)(i, s) Then
                                      ec = text_dev.send(s)
                                      Return waitfor(ec) AndAlso
                                             goto_next()
                                  Else
                                      Return False
                                  End If
                              End Function,
                              Function() As Boolean
                                  Return ec.end_result() AndAlso
                                         goto_end()
                              End Function)
    End Function

    Public Shared Function receive(ByVal i As text_pump,
                                   ByVal o As pointer(Of T),
                                   ByVal string_T As binder(Of _do_val_ref(Of String, T, Boolean), 
                                                               uri_conversion_binder_protector)) As event_comb
        assert(Not i Is Nothing)
        assert(string_T.has_value())
        Dim ec As event_comb = Nothing
        Dim p As pointer(Of String) = Nothing
        Return New event_comb(Function() As Boolean
                                  p = New pointer(Of String)()
                                  ec = i.receive(p)
                                  Return waitfor(ec) AndAlso
                                         goto_next()
                              End Function,
                              Function() As Boolean
                                  Dim r As T = Nothing
                                  Return (+string_T)(+p, r) AndAlso
                                         eva(o, r) AndAlso
                                         goto_end()
                              End Function)
    End Function

    Public Function receive(ByVal o As pointer(Of T)) As event_comb Implements dev_T(Of T).receive
        Return receive(text_dev, o, string_T)
    End Function
End Class

Public Class stream_text_dev_T_adapter(Of T)
    Implements dev_T(Of T)

    Public ReadOnly stream_text_dev As stream_text
    Private ReadOnly enc As Encoding
    Private ReadOnly T_string As binder(Of _do_val_ref(Of T, String, Boolean), uri_conversion_binder_protector)
    Private ReadOnly string_T As binder(Of _do_val_ref(Of String, T, Boolean), uri_conversion_binder_protector)

    Public Sub New(ByVal st As stream_text,
                   Optional ByVal enc As Encoding = Nothing,
                   Optional ByVal T_string As binder(Of _do_val_ref(Of T, String, Boolean), 
                                                        uri_conversion_binder_protector) = Nothing,
                   Optional ByVal string_T As binder(Of _do_val_ref(Of String, T, Boolean), 
                                                        uri_conversion_binder_protector) = Nothing)
        assert(Not st Is Nothing)
        assert(T_string.has_value())
        assert(string_T.has_value())
        Me.stream_text_dev = st
        Me.enc = If(enc Is Nothing, default_encoding, enc)
        Me.T_string = T_string
        Me.string_T = string_T
    End Sub

    Public Shared Function convert(ByVal i As stream_text,
                                   ByRef o As dev_T(Of T),
                                   Optional ByVal enc As Encoding = Nothing,
                                   Optional ByVal T_bytes As binder(Of _do_val_ref(Of T, String, Boolean), 
                                                                       uri_conversion_binder_protector) = Nothing,
                                   Optional ByVal bytes_T As binder(Of _do_val_ref(Of String, T, Boolean), 
                                                                       uri_conversion_binder_protector) = Nothing) _
                                  As Boolean
        o = New stream_text_dev_T_adapter(Of T)(i, enc, T_bytes, bytes_T)
        Return True
    End Function

    Public Shared Function convert(ByVal i As stream_text,
                                   ByVal o As pointer(Of dev_T(Of T)),
                                   Optional ByVal enc As Encoding = Nothing,
                                   Optional ByVal T_bytes As binder(Of _do_val_ref(Of T, String, Boolean), 
                                                                       uri_conversion_binder_protector) = Nothing,
                                   Optional ByVal bytes_T As binder(Of _do_val_ref(Of String, T, Boolean), 
                                                                       uri_conversion_binder_protector) = Nothing) _
                                  As event_comb
        Return sync_async(Function() As Boolean
                              Dim r As dev_T(Of T) = Nothing
                              Return convert(i, r, enc, T_bytes, bytes_T) AndAlso
                                     eva(o, r)
                          End Function)
    End Function

    Public Shared Function convert(ByVal i As dev_T(Of T), ByRef o As stream_text) As Boolean
        Dim a As stream_text_dev_T_adapter(Of T) = Nothing
        If cast(i, a) AndAlso
           assert(Not a Is Nothing) Then
            o = a.stream_text_dev
            Return True
        Else
            Return False
        End If
    End Function

    Public Function sense(ByVal pending As pointer(Of Boolean),
                          ByVal timeout_ms As Int64) As event_comb Implements sensor.sense
        Return stream_text_dev.sense(pending, timeout_ms)
    End Function

    Public Function send(ByVal i As T) As event_comb Implements dev_T(Of T).send
        Dim ec As event_comb = Nothing
        Dim ms As MemoryStream = Nothing
        Return New event_comb(Function() As Boolean
                                  Dim s As String = Nothing
                                  If (+T_string)(i, s) AndAlso
                                     memory_stream.create(s, enc, ms) Then
                                      assert(Not ms Is Nothing)
                                      ec = stream_text_dev.send(ms)
                                      Return waitfor(ec) AndAlso
                                             goto_next()
                                  Else
                                      Return False
                                  End If
                              End Function,
                              Function() As Boolean
                                  assert(Not ms Is Nothing)
                                  ms.Close()
                                  ms.Dispose()
                                  Return ec.end_result() AndAlso
                                         goto_end()
                              End Function)
    End Function

    Public Function receive(ByVal o As pointer(Of T)) As event_comb Implements dev_T(Of T).receive
        Return text_dev_T_adapter(Of T).receive(stream_text_dev, o, string_T)
    End Function
End Class
